import 'dart:convert';
import 'dart:io';

import 'package:gate_cli/exception/errors.dart';
import 'package:gate_cli/utils/print.dart';

/// Author: Shper
/// Created: 2023/9/6
class ProcessUtil {
  ProcessUtil._();

  static Future<bool> startProcess(String command, List<String> arguments,
      {String? workingDirectory,
      bool printResult = true,
      bool throwable = true}) async {
    final process = await Process.start(command, arguments,
        workingDirectory: workingDirectory);
    // 打印日志
    if (printResult) {
      // 监听进程的标准输出
      process.stdout.transform(utf8.decoder).listen((data) {
        print(data);
      });
      // 监听进程的标准 Warring、Error 输出
      process.stderr.transform(utf8.decoder).listen((data) {
        print(data);
      });
    }
    // 等待进程完成
    final exitCode = await process.exitCode;
    // 抛出异常
    if (throwable && exitCode != 0) {
      throw new CommandRunError(
          "startProcess Failed: command:$command  arguments:$arguments  \n err:${process.stderr.toString()}");
    } else if (exitCode != 0) {
      printYellow(
          "startProcess Failed: command:$command  arguments:$arguments  \n err:${process.stderr.toString()}");
    }
    return exitCode == 0;
  }

  static dynamic runProcessAndResult(String command, List<String> arguments,
      {String? workingDirectory,
      bool printResult = false,
      bool throwable = true}) {
    final process =
        Process.runSync(command, arguments, workingDirectory: workingDirectory);
    final exitCode = process.exitCode;
    // 抛出异常
    if (throwable && exitCode != 0) {
      throw new CommandRunError(
          "runProcessAndResult Failed: command:$command  arguments:$arguments  \n err:${process.stderr.toString()}");
    } else if (exitCode != 0) {
      printYellow(
          "runProcessAndResult Failed: command:$command  arguments:$arguments  \n err:${process.stderr.toString()}");
    }
    // 打印控制台信息
    if (printResult) {
      print(process.stdout);
    }
    return process.stdout;
  }

  static Future<bool> runProcessAndStardandResult(
      String command, List<String> arguments, String logPath,
      {String? workingDirectory,
      bool printResult = false,
      bool throwable = true}) async {
    final process =
        Process.runSync(command, arguments, workingDirectory: workingDirectory);
    final exitCode = await process.exitCode;
    // 抛出异常
    if (throwable && exitCode != 0) {
      printRed(
          "runProcessAndResult Failed: command:$command  arguments:$arguments  \n err:${process.stderr.toString()}");
    } else if (exitCode != 0) {
      printYellow(
          "runProcessAndResult Failed: command:$command  arguments:$arguments  \n err:${process.stderr.toString()}");
    }
    if (exitCode != 0) {
      final result = process.stderr.toString() + process.stdout.toString();
      final file = File(logPath);
      file.writeAsStringSync(result);
    }
    return exitCode == 0;
  }

  /// xcodebuild 错误日志解析
  static Future<void> iosBuildLogParser(logPath) async {
    String rawString = 'cat ${logPath} | grep error: ';
    final data = Process.runSync('/bin/zsh', ['-c', rawString]);
    String res = data.stdout.toString();
    printRed("this is the xcodebuild error log :\n $res");
    await data.exitCode;
  }
}
